#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Attributes:
    __version__ (str): "0.0.1"
    __copyright__ (str): "Copyright (C) 2025 z"
    __license__ (str): "MIT"
    __author__ (str): "Z"
"""

import time
import requests
import threading

from dingtalk_stream import AckMessage
import dingtalk_stream

from wingman import logger
from wingman.common.error import ErrorCode
from config.system import DINGTALK_APP_KEY, DINGTALK_APP_SECRET, FLASK_ROBOT_WEBHOOK, IS_DINGTALK_SEND


class MyEventHandler(dingtalk_stream.EventHandler):
    """ 定义事件处理器 """
    async def process(self, event: dingtalk_stream.EventMessage):
        # 处理接收到的事件,并发送到flask
        send_data_to_flask_thread = threading.Thread(target=send_data_to_flask,args=(event.data,))
        send_data_to_flask_thread.start()
        return AckMessage.STATUS_OK, 'OK'


class MyCallbackHandler(dingtalk_stream.CallbackHandler):
    """ 处理接收到的回调消息,并发送到flask """
    async def process(self, message: dingtalk_stream.CallbackMessage):
        send_data_to_flask_thread = threading.Thread(target=send_data_to_flask,args=(message.data,))
        send_data_to_flask_thread.start()
        return AckMessage.STATUS_OK, 'OK'


def send_data_to_flask(data, allowed_origin=None):
    """钉钉 stream 消息回送"""
    url = FLASK_ROBOT_WEBHOOK
    headers = {'Content-Type': 'application/json'}

    if allowed_origin:
        headers['Access-Control-Allow-Origin'] = allowed_origin

    max_retries = 5
    retry_delay = 1
    result = None

    for attempt in range(max_retries):
        try:
            result = requests.post(url, json=data, headers=headers)
            result.raise_for_status()
            # 解析 Flask 返回的响应
            response_data = result.json()
            # 使用会话 webhook 发送消息到钉钉群
            if 'sessionWebhook' in data:
                session_webhook = data['sessionWebhook']
                message = {
                    "msgtype": "text",
                    "text": {
                        "content": f"{response_data.get('result_msg', '操作完成')}"
                    }
                }
                webhook_response = requests.post(
                    session_webhook, 
                    json=message, 
                    headers={'Content-Type': 'application/json'}
                )
                webhook_response.raise_for_status()
            break  # 如果成功则跳出循环
        except requests.exceptions.RequestException as e:
            logger.warning(ErrorCode.WARNING_STREAM_REQUESTS.value, f"发送数据到flask失败,尝试 {attempt + 1}/{max_retries}。错误: {str(e)}", __name__)
            if attempt < max_retries - 1:
                time.sleep(retry_delay)
                retry_delay *= 2
            else:
                logger.error(ErrorCode.STREAM_REQUESTS.value, f"所有重试均失败,最后错误: {str(e)}", __name__)
                raise
    return result.text if result else ""


def start_dingtalk_client():
    """
    启动钉钉Stream客户端
    钉钉应用的App Key和App Secret
    """
    credential = dingtalk_stream.Credential(DINGTALK_APP_KEY, DINGTALK_APP_SECRET)
    client = dingtalk_stream.DingTalkStreamClient(credential)
    client.register_all_event_handler(MyEventHandler())
    client.register_callback_handler(dingtalk_stream.ChatbotMessage.TOPIC, MyCallbackHandler())
    try:
        client.start_forever()
    except Exception as e:
        print(f"Error starting DingTalk client: {e}")


def main():
    """
    启动钉钉Stream客户端线程
    保持主线程持续运行
    """
    try:
        if IS_DINGTALK_SEND:
            thread = threading.Thread(target=start_dingtalk_client)
            thread.start()
            while True:
                time.sleep(5)
    except KeyboardInterrupt:
        logger.warning(ErrorCode.STREAM_OUT.value, "dingding stream 正在关闭程序...", __name__)


if __name__ == "__main__":
    main()
